/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[OptionPanelComponent.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package swing.components;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

/**
 * Swing弹出对话框组件
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class OptionPanelComponent {

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			@Override
			public void run() {
				OptionPanelFrame frame = new OptionPanelFrame();
				frame.setVisible(true);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			}
		});
	}
}

/**
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class OptionPanelFrame extends JFrame {

	private static final long serialVersionUID = 5121170798057493216L;

	private static final int DEFAULT_WIDTH = 600;
	private static final int DEFAULT_HEIGHT = 400;

	private OptionPanel typePanel = null;// 对话框类型
	private OptionPanel iconTypePanel = null;// 左侧图标类型
	private OptionPanel messagePanel = null; // 对话框显示的消息类型
	private OptionPanel optionButtonPanel = null;// 底部按钮类型
	private OptionPanel optionsPanel = null;// 选项类型
	private OptionPanel inputPanel = null;// 输入框类型

	// 用于显示的各种消息
	private String stringMessage = "Message";
	private Icon iconMessage = null;
	private Object objectMessage = new java.util.Date();
	private Component componentMessage = new SampleComponent();

	public OptionPanelFrame() {
		setTitle("Option Panel Test");
		this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		setLocationByPlatform(true);
		setResizable(false);

		try {
			iconMessage = new ImageIcon(ImageIO.read(new File("src/__/icon.gif")));
		} catch (IOException e) {
			e.printStackTrace();
		}

		JPanel gridPanel = new JPanel();
		gridPanel.setLayout(new GridLayout(2, 3));// 使用网格布局管理器

		// 对话框类型
		typePanel = new OptionPanel("对话框类型", "Message", "Confirm", "Option", "Input");
		// 左侧图标类型: 其中PLAIN_MESSAGE没有图标
		iconTypePanel = new OptionPanel("左侧图标类型", "ERROR_MESSAGE", "INFORMATION_MESSAGE", "WARNING_MESSAGE",
				"QUESTION_MESSAGE", "PLAIN_MESSAGE");
		// 对话框显示的消息类型: 最常见为字符串
		messagePanel = new OptionPanel("对话框显示的消息类型", "String", "Icon", "Component", "Other", "Object[]");
		// 底部按钮类型: 其取决于对话框类型和选项类型
		optionButtonPanel = new OptionPanel("底部按钮类型", "DEFAULT_OPTION", "YES_NO_OPTION", "YES_NO_CANCLE_OPTION",
				"OK_CANCEL_OPTION");
		// 选项类型
		optionsPanel = new OptionPanel("选项类型", "String[]", "Icon[]", "Object[]");
		// 输入框类型
		inputPanel = new OptionPanel("输入框类型", "Text Field", "Combo Box");

		gridPanel.add(typePanel);
		gridPanel.add(iconTypePanel);
		gridPanel.add(messagePanel);
		gridPanel.add(optionButtonPanel);
		gridPanel.add(optionsPanel);
		gridPanel.add(inputPanel);

		JPanel showPanel = new JPanel();
		JButton showButton = new JButton("Show");
		showButton.addActionListener(new ShowAction());
		showPanel.add(showButton);

		getContentPane().add(gridPanel, BorderLayout.CENTER);
		getContentPane().add(showPanel, BorderLayout.SOUTH);
	}

	/**
	 * 
	 * @author 不落的太阳(Sean Yang aka ShortPeace)
	 * @version 1.0
	 * @since jdk 1.8
	 *
	 */
	private class ShowAction implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent event) {
			if (typePanel.getSelection().equals("Confirm")) {
				JOptionPane.showConfirmDialog(OptionPanelFrame.this, getMessage(), "Title", getType(optionButtonPanel));
			} else if (typePanel.getSelection().equals("Input")) {
				if (inputPanel.getSelection().equals("Text Field")) {
					JOptionPane.showInputDialog(OptionPanelFrame.this, getMessage(), "Title", getType(iconTypePanel));
				} else {
					JOptionPane.showInputDialog(OptionPanelFrame.this, getMessage(), "Title", getType(iconTypePanel),
							null, new String[] { "Yellow", "Blue", "Red" }, "Blue");
				}
			} else if (typePanel.getSelection().equals("Message")) {
				JOptionPane.showMessageDialog(OptionPanelFrame.this, getMessage(), "Title", getType(iconTypePanel));
			} else if (typePanel.getSelection().equals("Option")) {
				JOptionPane.showOptionDialog(OptionPanelFrame.this, getMessage(), "Title", getType(optionButtonPanel),
						getType(iconTypePanel), null, getOptions(), getOptions()[0]);
			}
		}
	}

	/**
	 * 根据Option的类型获得当前显示的消息
	 * 
	 * @return 显示的消息
	 */
	public Object getMessage() {
		String temp = messagePanel.getSelection();
		if (temp.equals("String")) {
			return stringMessage;
		} else if (temp.equals("Icon")) {
			return iconMessage;
		} else if (temp.equals("Component")) {
			return componentMessage;
		} else if (temp.equals("Object[]")) {
			return new Object[] { stringMessage, iconMessage, componentMessage, objectMessage };
		} else if (temp.equals("Other")) {
			return objectMessage;
		} else {
			return null;
		}
	}

	/**
	 * 获得当前的选项
	 * 
	 * @return 当前的选项
	 */
	public Object[] getOptions() {
		String temp = optionsPanel.getSelection();
		if (temp.equals("String[]")) {
			return new String[] { "Yellow", "Blue", "Red" };
		} else if (temp.equals("Icon[]")) {
			return new Icon[] { iconMessage, iconMessage, iconMessage };
		} else if (temp.equals("Object[]")) {
			return new Object[] { stringMessage, iconMessage, componentMessage };
		} else {
			return null;
		}
	}

	/**
	 * 获得所选的消息或者选项类型
	 * 
	 * @param optionPanel
	 * @return 选项类型
	 */
	public int getType(OptionPanel optionPanel) {
		String temp = optionPanel.getSelection();

		try {
			return JOptionPane.class.getField(temp).getInt(null);
		} catch (Exception e) {
			return -1;
		}
	}
}

/**
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class OptionPanel extends JPanel {

	private static final long serialVersionUID = -1665785687421287758L;

	private ButtonGroup group = null;

	public OptionPanel(String title, String... options) {
		// 设置边框类型
		setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), title));
		// 设置布局管理器
		setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

		group = new ButtonGroup();
		// 设置单选按钮
		for (String option : options) {
			JRadioButton radioButton = new JRadioButton(option);
			radioButton.setActionCommand(option);
			group.add(radioButton);
			this.add(radioButton);
			radioButton.setSelected(option == options[0]);
		}
	}

	/**
	 * 获得当前的选项
	 * 
	 * @return 当前的选项
	 */
	public String getSelection() {
		return group.getSelection().getActionCommand();
	}
}

/**
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 *
 */
class SampleComponent extends JComponent {

	private static final long serialVersionUID = 1348654877466355386L;

	/**
	 * 绘制组件
	 * 
	 * @param g
	 */
	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		Rectangle2D rect = new Rectangle2D.Double(0, 0, getWidth() - 1, getHeight() - 1);
		g2.fill(rect);
		g2.setPaint(Color.YELLOW);
		g2.draw(rect);
	}

	/**
	 * 获得组件预设的大小
	 * 
	 * @return 组件预设大小
	 */
	@Override
	public Dimension getPreferredSize() {
		return new Dimension(10, 10);
	}
}
